package com.example.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * 日志切面
 * 为所有方法添加日志记录功能
 */
@Aspect
@Component
public class LoggingAspect {
    
    /**
     * 定义切点：所有service包下的方法
     */
    @Pointcut("execution(* com.example.service.*.*(..))")
    public void servicePointcut() {}
    
    /**
     * 环绕通知：记录方法执行时间和参数
     */
    @Around("servicePointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        Logger logger = LoggerFactory.getLogger(joinPoint.getTarget().getClass());
        String methodName = joinPoint.getSignature().getName();
        String className = joinPoint.getTarget().getClass().getSimpleName();
        
        // 记录方法开始
        logger.info("开始执行方法: {}.{}", className, methodName);
        
        // 记录参数
        Object[] args = joinPoint.getArgs();
        if (args.length > 0) {
            StringBuilder paramLog = new StringBuilder("参数: ");
            for (int i = 0; i < args.length; i++) {
                if (i > 0) paramLog.append(", ");
                paramLog.append(args[i]);
            }
            logger.info(paramLog.toString());
        }
        
        long startTime = System.currentTimeMillis();
        Object result = null;
        
        try {
            result = joinPoint.proceed();
            long endTime = System.currentTimeMillis();
            logger.info("方法执行成功: {}.{}, 耗时: {}ms", className, methodName, endTime - startTime);
            return result;
        } catch (Throwable e) {
            long endTime = System.currentTimeMillis();
            logger.error("方法执行异常: {}.{}, 耗时: {}ms, 异常: {}", 
                        className, methodName, endTime - startTime, e.getMessage());
            throw e;
        }
    }
    
    /**
     * 异常通知：记录异常信息
     */
    @AfterThrowing(pointcut = "servicePointcut()", throwing = "ex")
    public void afterThrowing(JoinPoint joinPoint, Throwable ex) {
        Logger logger = LoggerFactory.getLogger(joinPoint.getTarget().getClass());
        String methodName = joinPoint.getSignature().getName();
        String className = joinPoint.getTarget().getClass().getSimpleName();
        
        logger.error("方法执行异常: {}.{}, 异常类型: {}, 异常信息: {}", 
                    className, methodName, ex.getClass().getSimpleName(), ex.getMessage());
    }
}
